import 'package:common/widget/progress_dialog.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:resource/generated/l10n.dart';
import 'package:toast/toast.dart';
import '../constant/route_name_config.dart';
import '../network/business_response.dart';
import '../network/code_msg_model.dart';
import '../utils/function_define.dart';
import '../utils/log_util.dart';
import '../widget/loading_dialog.dart';

///https://zhuanlan.zhihu.com/p/392550893?utm_id=0
//https://img-blog.csdnimg.cn/img_convert/324e9869b25441d6c05bd6b30b7bb384.jpeg
abstract class BaseState<W extends StatefulWidget> extends State<W>
    with AutomaticKeepAliveClientMixin
    implements BusinessResponse {

  RxString rxTitle = ''.obs;
  bool isShowLoading = false;
  bool isShowProgress = false;
  bool isShowLogout = false;
  Map<String,dynamic>? args;

  // 是否开启页面缓存,
  // debug模式下不需要缓存页面，
  // 缓存会影响页面的调试效率
  @override
  bool get wantKeepAlive => onNeedCachePage() && !kDebugMode;

  CancelToken cancelToken = CancelToken();


  @protected
  bool onNeedCachePage() {
    return true;
  }

  ///该函数为 State 初始化在createState后调用，
  ///只会被调用一次，因此，
  ///通常会在该回调中做一些一次性的操作，
  ///如执行 State 各变量的初始赋值、订阅子树的事件通知、
  ///与服务端交互，获取服务端数据后调用 setState 来设置 State。
  @override
  void initState() {
    super.initState();
    LogUtil.stdPrint('page name ${widget.runtimeType}');
    onStateInit();
    //build 之后调用
    //当你定义一个函数，但某些参数在函数体中不会被使用时，可以使用_来忽略这些参数
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (onNeedRequestPermission()) {
        requestPermission();
      }
      onLoadData();
    });
  }

  ///状态初始化时调用
  @protected
  void onStateInit();

  //此回调是专门为了开发调试而提供的，
  // 在热重载(hot reload)时会被调用，
  // 此回调在 Release 模式下永远不会被调用。
  @override
  void reassemble() {
    super.reassemble();
    onLoadData();
  }

  /// State对象依赖发生变化时调用；
  /// 系统语言、主题修改，系统也会通知调用
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  /// 横竖屏切换时调用
  @override
  void didUpdateWidget(covariant W oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  ///主要是返回需要渲染的 Widget，
  ///由于 build 会被调用多次，因此在该函数中只能做返回 Widget 相关逻辑，
  ///避免因为执行多次而导致状态异常。
  @override
  Widget build(BuildContext context) {
    super.build(context);
    onBuildWidget(context);
    Scaffold baseScaffold = Scaffold(
      backgroundColor: Colors.grey[100],
      appBar: onAppBarCreate(),
      ///PopScope监听返回键
      body: PopScope(
          onPopInvoked: (didPop) {
            onPopCalled(didPop);
            isShowLoading = false;
          },
          canPop: onScopeCanPop(),
          child:  Stack(children: <Widget>[onBodyCreate()]),
      ),
      bottomNavigationBar: onBottomBarCreate(),
      floatingActionButton: onFloatingActionButton(),
    );
    return baseScaffold;

  }
  @protected
  void onBuildWidget(BuildContext context){
    Object? obj = ModalRoute.of(context)?.settings.arguments;
    if(obj is Map){
       args = ModalRoute.of(context)?.settings.arguments as Map<String,dynamic>;
    }
    ToastContext().init(context);
  }

  //显示加载对话框
  Future<void> showDelayLoadingDialog(BuildContext context) async {
    Future.delayed(const Duration(milliseconds: 500), () {
      showLoadingDialog(context);
    });

  }

  //显示加载对话框
  Future<void> showLoadingDialog(BuildContext context) async {
    if(!isShowLoading){
      isShowLoading = true;
      return showDialog<void>(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return PopScope(
                onPopInvoked: (didPop) {
                  if (didPop){
                    isShowLoading = false;
                  }
                },
                canPop: true,
                child: const LoadingDialog());
          });
    }
  }

  //显示进度对话框
  Future<void> showProgressDialog(BuildContext context,RxDouble progressValue) async {
    if (!isShowProgress) {
      isShowProgress = true;
      return showDialog<void>(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return PopScope(
                onPopInvoked: (didPop) {
                  if (didPop){
                    isShowProgress = false;
                  }
                },
                canPop: true,
                child: ProgressDialog(progressValue: progressValue));
          });
    }
  }

  //显示进度对话框
  Future<void> showLogoutDialog(BuildContext context) async {
    if (!isShowLogout) {
      isShowLogout = true;
      return showDialog<void>(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return PopScope(
                onPopInvoked: (didPop) {
                  if (didPop){
                    isShowLogout = false;
                  }
                },
                canPop: true,
                child: AlertDialog(
                  title: Text(S.current.hint),
                  content: Text(S.current.token_expired),
                  actions: <Widget>[
                    TextButton(
                      child: Text(S.current.cancel),
                      onPressed: () {
                        isShowLogout = false;
                        Navigator.of(context).pop();
                      },
                    ),
                    TextButton(
                      child: Text(S.current.go_login),
                      onPressed: () {
                        isShowLogout = false;
                        Navigator.of(context).popAndPushNamed(RouteNameConfig.kLoginPage);
                      },
                    )
                  ],
                ));
          });
    }
  }

  ///创建视图时调用
  @protected
  PreferredSizeWidget? onAppBarCreate() {
    if (onNeedAppBar()) {
      return AppBar(
          title: Obx(() => Text(rxTitle.value)),
          leading: onNeedBack()
              ? IconButton(
                  onPressed: () {
                    onBackPressed();
                  },
                  icon: const Image(
                    gaplessPlayback: true,
                    image: AssetImage("assets/images/xxhdpi/arrow_left_white.png",
                        package: "resource"),
                  ))
              : null,
          leadingWidth: 35,
          centerTitle: true,
          automaticallyImplyLeading: false,
          actions: onCreateAppBarActions(),
      );
    }else {
      return null;
    }
  }

  ///是否需要工具栏
  bool onNeedAppBar(){
    return true;
  }

  ///是否需要返回按钮
  bool onNeedBack(){
    return true;
  }

  ///监听侧滑返回
  @protected
  void onPopCalled(bool didPop){
  }
  ///右上角操作按钮
  List<Widget>? onCreateAppBarActions(){
    return null;
  }

  @protected
  bool onScopeCanPop(){
    return true;
  }

  ///监听左上角返回,监听侧滑返回
  @protected
  void onBackPressed() {
    if (Navigator.canPop(context)) {
      Navigator.pop(context);
    } else {
      //其实他就是对  Navigator.pop的封装，但是如果只有一个页面的时候它不会跳，
      //如果不调用这个，无法触发onPop
      Navigator.maybePop(context);
      SystemNavigator.pop();
    }
  }

  ///创建视图时调用
  @protected
  Widget onBodyCreate();

  ///创建视图时调用
  @protected
  Widget? onBottomBarCreate() {
    return null;
  }

  @protected
  Widget? onFloatingActionButton() {
    return null;
  }

  @protected
  bool onNeedRequestPermission() {
    return false;
  }

  @protected
  void onLoadData() {}

  ///在组件被移除节点后会被调用，如果该组件被移除节点，
  ///然后未被插入到其他节点时，则会继续调用 dispose 永久移除。
  @override
  void deactivate() {
    super.deactivate();
  }

  ///Widget 处于deactivate状态下调用
  @protected
  void onStop(){
  }

  ///永久移除组件，并释放组件资源。调用完 dispose 后，
  ///mounted 属性被设置为 false，也代表组件生命周期的结束。
  @override
  void dispose() {
    super.dispose();
    onGetCancelToken().cancel();
    onDestroy();
  }
  ///Widget 被彻底移除时调用
  @protected
  void onDestroy(){
  }

  @override
  CancelToken onGetCancelToken() {
    return cancelToken;
  }

  void dismissLoadingDialog(){
    if(mounted && Navigator.canPop(context) && isShowLoading){
      isShowLoading = false;
      Navigator.pop(context);
    }
  }

  void dismissProgressDialog(){
    if(mounted && Navigator.canPop(context) && isShowProgress){
      isShowProgress = false;
      Navigator.pop(context);
    }
  }

  ///接口请求失败
  @override
  void onFail(CodeMsgModel baseResponseModel) {
    dismissLoadingDialog();
    dismissProgressDialog();
    StringBuffer stringBuffer = StringBuffer();
    stringBuffer.write(baseResponseModel.msg);
    stringBuffer.write("[code:${baseResponseModel.code}]");
    Toast.show(stringBuffer.toString(),duration: Toast.lengthLong,gravity: Toast.bottom);
  }
  ///接口请求成功
  @override
  void onSuccess<D>(D d,String apiPath) {
    dismissLoadingDialog();
    dismissProgressDialog();
  }

  ///接口请求token过期
  @override
  void onLogOut(CodeMsgModel baseResponseModel) {
    dismissLoadingDialog();
    dismissProgressDialog();
    showLogoutDialog(context);
  }
}